home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / ja91 / ASCII / CAMG / CAMG.txt
Encoding:
Text File  |  1991-08-09  |  11.6 KB  |  334 lines

  1. (c)  Copyright 1991 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice,
  3. and is provided "as is" without warranty of any kind, either expressed
  4. or implied.  The entire risk as to the use of this information is
  5. assumed by the user.
  6.  
  7.  
  8.  
  9. ECS Display Modes
  10. and ILBM CAMG
  11.  
  12.  
  13. By Carolyn Scheppner
  14.  
  15.  
  16. Under versions of the Amiga operating system and hardware prior to release
  17. 2.0, the display modes available to the system (such as HIRES, LACE, HAM,
  18. HALFBRITE, DUALPF) could all be described in the 16-bit ViewPort.Modes field.
  19. When saving an Amiga display to an ILBM file, the ViewPort mode field, also
  20. referred to as a view mode, was preserved along with the image to make sure
  21. it could be later displayed in the proper display mode.  The ILBM CAMG chunk
  22. stores a display's view mode.
  23.  
  24. When using Amiga operating systems prior to release 2.0, storing the view
  25. mode in an ILBM involves extracting the 16-bit view mode, masking out the
  26. GENLOCK_AUDIO, GENLOCK_VIDEO, VP_HIDE, and SPRITES flags, and storing the
  27. result as a 32-bit value in the CAMG chunk.  The upper word of the value
  28. should be zero.  Reading the view mode requires masking out the undesirable
  29. bits mentioned above from the CAMG's 32-bit value, and then use the low word
  30. of the result as a 16-bit value for ViewPort.Modes or NewScreen.ViewModes
  31. when opening a display.
  32.  
  33. The 2.0 operating system and the ECS chips support a large number of display
  34. modes--too many for the old 16-bit view mode to represent.  Under 2.0,
  35. display modes are now specified by a 32-bit ModeID which is not stored in the
  36. ViewPort, but is instead held in private graphics lists.  The
  37. graphics.library provides functions for accessing this extended display
  38. information.  The GetVPModeID() function returns a ViewPort's 32-bit ModeID:
  39.  
  40.         ULONG  modeID = GetVPModeID(struct ViewPort *vp);
  41.  
  42. When saving a display under release 2.0, an ILBM writer must preserve the
  43. entire 32-bit modeID in the CAMG chunk.  The advantage of this is ILBM
  44. readers that don't know about the release 2.0 32-bit view mode can still
  45. display ILBMs saved under 2.0.  Although ModeIDs are numeric values rather
  46. than bit masks, the 2.0 ModeIDs were designed to contain the pre-2.0 bits in
  47. their low word for the matching (or closest match) old ViewPort mode.  For
  48. example, the 2.0 ModeID for a Hires-Interlace display has the HIRES and LACE
  49. bits set in its low word.  The 2.0 ModeID for a Productivity Interlaced
  50. display also has the HIRES and LACE bits set in its low word because, of the
  51. display modes available to a non-ECS or pre-2.0 system, a Hires-Interlace
  52. display is most like the Productivity Interlaced display.
  53.  
  54. By storing the entire 32-bit ModeID in the CAMG chunk, 2.0 compatible ILBM
  55. readers can display the image in the proper display mode if that display mode
  56. is available to the current system.  Old ILBM readers will not be able to use
  57. the new display modes, but they will truncate the new 32-bit ModeID into a
  58. 16-bit view mode which will normally provide a reasonable view mode for the
  59. image.
  60.  
  61. There are several CAMG values saved by old ILBM writers which are invalid
  62. modeID values.  An ILBM writer will produce ILBMs with invalid modeID values
  63. if it:
  64.  
  65. o  fails to mask out SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO.
  66. o  saves a 2.0 extended view mode as 16 bits rather than saving the 32-bit
  67.    modeID returned by GetVPModeID().
  68. o  saves garbage in the upper word of the
  69. CAMG value.
  70.  
  71. All valid modeIDs either have an upper word of 0 and do not have the
  72. <graphics/view.h> EXTENDED_MODE bit set in the low word, or have a non-0
  73. upper word and do have the EXTENDED_MODE bit set in the lower word.  CAMG
  74. values which are invalid modeIDs must be screened out and fixed before using
  75. them.
  76.  
  77.  
  78. /* Knock bad bits out of old-style CAMGs modes before checking availability.
  79.  * (some ILBM CAMG's have these bits set in old 1.3 modes, and should not)
  80.  * If not an extended monitor ID, or if marked as extended but missing
  81.  * upper 16 bits, screen out inappropriate bits now.
  82.  */
  83. if((!(modeid & MONITOR_ID_MASK)) ||
  84.     ((modeid & EXTENDED_MODE)&&(!(modeid & 0xFFFF0000))))
  85.         modeid &=
  86.            (~(EXTENDED_MODE|SPRITES|GENLOCK_AUDIO|GENLOCK_VIDEO|VP_HIDE));
  87.  
  88. /* Check for bogus CAMG like some brushes have, with junk in
  89.  * upper word and extended bit NOT set not set in lower word.
  90.  */
  91. if((modeid & 0xFFFF0000)&&(!(modeid & EXTENDED_MODE)))
  92.     {
  93.     /* Bad CAMG, so ignore CAMG and determine a mode based on
  94.      * based on pagesize or aspect
  95.      */
  96.      modeid = NULL;
  97.      if(wide >= 640)    modeid |= HIRES;
  98.      if(high >= 400)    modeid |= LACE;
  99.      }
  100.  
  101.  
  102.  
  103. The following example, camg.c, illustrates how to handle the possible CAMG
  104. values.
  105.  
  106. ;/* Camg.c - Execute me to compile me with SAS C 5.10
  107. LC -b1 -cfistq -v -y -j73 camg.c
  108. Blink FROM LIB:c.o,camg.o TO camg LIBRARY LIB:LC.lib,LIB:Amiga.lib
  109. quit
  110. */
  111.  
  112. /*
  113.  * Camg.c Demonstrates use of ILBM.CAMG value. Filters out junk CAMGs and bad
  114.  * bits. Adapts to 2.0 and 1.3
  115.  *
  116.  * Note - Under 2,0, when writing a CAMG you should write the 32-bit value
  117.  * returned by the 2.0 graphics function GetVPModeID(viewport);
  118.  */
  119.  
  120. #include <exec/types.h>
  121. #include <exec/libraries.h>
  122. #include <intuition/intuition.h>
  123. #include <graphics/displayinfo.h>
  124.  
  125. #include <clib/exec_protos.h>
  126. #include <clib/intuition_protos.h>
  127. #include <clib/graphics_protos.h>
  128.  
  129. #include <stdio.h>
  130.  
  131. struct Screen  *openidscreen(SHORT wide, SHORT high, SHORT deep, ULONG modeid);
  132. ULONG           modefallback(ULONG modeid, SHORT wide, SHORT high, SHORT deep);
  133.  
  134. #define DEBUG
  135.  
  136. struct Library *GfxBase;
  137. struct Library *IntuitionBase;
  138.  
  139. void            main(int argc, char **argv)
  140. {
  141.     struct Screen  *screen;
  142.  
  143.     /*
  144.      * Test the routines by passing various bad or possibly unavailable CAMG
  145.      * modeid values
  146.      */
  147.     if (GfxBase = OpenLibrary("graphics.library", 0))
  148.     {
  149.         if (IntuitionBase = OpenLibrary("intuition.library", 0))
  150.         {
  151.             /* Junk CAMG    */
  152.             if (screen = openidscreen(640, 400, 3, 0x12340000))
  153.                 CloseScreen(screen);
  154.  
  155.             /* Bad bits like VP_HIDE and SPRITES */
  156.             if (screen = openidscreen(320, 400, 3, 0x00006004))
  157.                 CloseScreen(screen);
  158.  
  159.             /* Extended bit set but not a valid modeid */
  160.             if (screen = openidscreen(320, 400, 3, 0x00009004))
  161.                 CloseScreen(screen);
  162.  
  163.             /* An ECS Mode - demonstrates modefallback if not available */
  164.             if (screen = openidscreen(640, 400, 2, 0x00039025))
  165.                 CloseScreen(screen);
  166.  
  167.             CloseLibrary(IntuitionBase);
  168.         }
  169.         CloseLibrary(GfxBase);
  170.     }
  171. }
  172.  
  173.  
  174. struct NewScreen ns = {NULL};
  175.  
  176. /*
  177.  * simple openidscreen
  178.  *
  179.  * Passed width, height, depth, and modeid, attempts to open a 2.0 or 1.3 screen.
  180.  * Demonstrates filtering out of bad CAMGs and modefallback() for unavailable
  181.  * modes.
  182.  */
  183.  
  184. struct Screen  *
  185. openidscreen(SHORT wide, SHORT high, SHORT deep, ULONG modeid)
  186. {
  187.     extern struct Libary *GfxBase;
  188.     struct Screen  *screen = NULL;
  189.  
  190. #ifdef DEBUG
  191.     printf("\nAsked to open screen with modeid $%08lx\n", modeid);
  192. #endif
  193.  
  194.     /*
  195.      * BEFORE USING A CAMG YOU HAVE READ, YOU MUST SCREEN OUT JUNK CAMGs AND
  196.      * INAPPROPRIATE BITS IN OLD 16-BIT CAMGs. YOU MAY WANT TO PLACE THESE
  197.      * FIRST TWO TESTS WITH YOUR CAMG-READING CODE TO SCREEN OUT BAD CAMGs
  198.      * IMMEDIATELY.
  199.      */
  200.  
  201.     /*
  202.      * Knock bad bits out of old-style CAMG modes before checking availability.
  203.      * (some ILBM CAMG's have these bits set in old 1.3 modes, and should not)
  204.      * If not an extended monitor ID, or if marked as extended but missing
  205.      * upper 16 bits, screen out inappropriate bits now.
  206.      */
  207.     if ((!(modeid & MONITOR_ID_MASK)) ||
  208.         ((modeid & EXTENDED_MODE) && (!(modeid & 0xFFFF0000))))
  209.         modeid &=
  210.             (~(EXTENDED_MODE | SPRITES | GENLOCK_AUDIO | GENLOCK_VIDEO | VP_HIDE));
  211.  
  212.     /*
  213.      * Check for bogus CAMG like some brushes have, with junk in upper word and
  214.      * extended bit NOT set not set in lower word.
  215.      */
  216.     if ((modeid & 0xFFFF0000) && (!(modeid & EXTENDED_MODE)))
  217.     {
  218.         /*
  219.          * Bad CAMG, so ignore CAMG and determine a mode based on based on
  220.          * pagesize or aspect
  221.          */
  222.         modeid = NULL;
  223.         if (wide >= 640)
  224.             modeid |= HIRES;
  225.         if (high >= 400)
  226.             modeid |= LACE;
  227.     }
  228.  
  229. #ifdef DEBUG
  230.     printf("After filtering, mode is now $%08lx\n", modeid);
  231. #endif
  232.  
  233.     /*
  234.      * Now see if mode is available
  235.      */
  236.     if (GfxBase->lib_Version >= 36)
  237.     {
  238.         /* if mode is not available, try a fallback mode */
  239.         if (ModeNotAvailable(modeid))
  240.             modeid = modefallback(modeid, wide, high, deep);
  241.  
  242.  
  243.         if (!(ModeNotAvailable(modeid)))         /* if mode is available */
  244.         {
  245.             /*
  246.              * We have an available mode id Here you may wish to create a
  247.              * custom, or centered, or overscan display clip based on the size
  248.              * of the image.  Or just use one of the standard clips.
  249.              *
  250.              * The 2.0 Display program uses QueryOverscan to get the settings of
  251.              * this modeid's OSCAN_TEXT, OSCAN_STANDARD, and OSCAN_MAX. Display
  252.              * centers the screen (via TopEdge and LeftEdge) within the user's
  253.              * closest OSCAN rectangle, and creates a display clip by using the
  254.              * same values and then clipping the values to be within OSCAN_MAX
  255.              * limits.  If the centered screen ends up lower than user's
  256.              * OSCAN_TEXT settings, I move it up to same MinY as his OSCAN_TEXT
  257.              * --- otherwise his Workbench might peek over the top.
  258.              */
  259.  
  260.             /*
  261.              * Now use extended OpenScreen or OpenScreenTags for this modeid.
  262.              * (this gives you the benefit of system-supported overscan, etc.)
  263.              */
  264. #ifdef DEBUG
  265.             printf("Doing OpenScreenTags of modeid $%08lx\n", modeid);
  266. #endif
  267.             screen = OpenScreenTags(NULL,
  268.                                     SA_Width, wide,
  269.                                     SA_Height, high,
  270.                                     SA_Depth, deep,
  271.                                     SA_DisplayID, modeid);
  272.         }
  273.     }
  274.  
  275.  
  276.     if (!screen) /* not 2.0, or mode not
  277.                   * available, or can't open */
  278.     {
  279.         /*
  280.          * Try an old-style OpenScreen with modefallback() modeid
  281.          */
  282.  
  283.         modeid = modefallback(modeid, wide, high, deep);
  284.  
  285.         ns.Width = wide;
  286.         ns.Height = high;
  287.         ns.Depth = deep;
  288.         ns.ViewModes = modeid;
  289.  
  290. #ifdef DEBUG
  291.         printf("Doing old OpenScreen of mode $%04lx\n", modeid);
  292. #endif
  293.  
  294.         screen = OpenScreen(&ns);
  295.     }
  296.  
  297.     return (screen);
  298. }
  299.  
  300.  
  301.  
  302. /*
  303.  * modefallback - passed an unavailable modeid, attempts to provide an
  304.  * available replacement modeid to use instead
  305.  */
  306.  
  307. ULONG
  308. modefallback(ULONG modeid, SHORT wide, SHORT high, SHORT deep)
  309. {
  310.     extern struct Library *GfxBase;
  311.     ULONG           newmodeid;
  312.  
  313.     /*
  314.      * Here you should either be asking the user what mode they want OR
  315.      * searching the display database and choosing an appropriate replacement
  316.      * mode based on what you or the user deem important (colors, or aspect, or
  317.      * size, etc.).  You could also use a built in table for modes you know
  318.      * about, and substitute mode you wish to use when the desired mode is not
  319.      * available.
  320.      *
  321.      * This simple routine simply masks out everything but old modes. This is a
  322.      * way to get some kind of display open but not necessarily a suitable or
  323.      * compatible display.
  324.      */
  325.  
  326.     newmodeid = modeid & (HIRES | LACE | HAM | EXTRA_HALFBRITE);
  327.  
  328. #ifdef DEBUG
  329.     printf("Modefallback passed 0x%08lx, returning 0x%08lx\n", modeid, newmodeid);
  330. #endif
  331.  
  332.     return (newmodeid);
  333. }
  334.